var jyrcid = null;



function JSJyRCClient() { // this is an abstract class; see at the bottom what to override
	var client = this;

	this.canRun = function() {
		return (window.XMLHttpRequest || window.ActiveXObject) && this.toSource;
	}



	this.jyrcid = null;
	this.jyrcServletURI = "http://jyrc.ymer.info/JyRCServlet";
	this.checkoutInterval = 997; // 997 is a prime number
	this.isDaemonized = false;

	this.daemonize = function() {
		this.notify("Welcome.\nPlease wait while connecting to the JyRC server...");
		this.isDaemonized = true;
		this.checkout();
	}
	this.checkout = function() { // you shouldn't invoke this function directly; use this.daemonize() instead
		if(!this.jyrcid) {
			this.jyrcid = "<*>";
			var req = newAJAXRequest();
			req.open('GET', this.jyrcServletURI, true);
			req.onreadystatechange = function() { if(req.readyState != 4) return;
				if(req.status != 200) {
					alert("I wasn't able to reach the JyRCServlet at "+this.jyrcServletURI
							+" (an http "+req.status+" error occured). Sorry.");
					history.back();
					return;
				}
				jyrcid = req.responseText.split("|",1)[0];
			}
			req.send(null);
		} else if(this.jyrcid == "<*>") {
			if(jyrcid) {
				client.jyrcid = jyrcid;
				this.jyrcid = jyrcid;
				jyrcid = null;
				this.notify("You're now connected to the JyRC server at "+this.jyrcServletURI+". Enjoy ;) ");
				this.refreshUserList();
			} else {}
		} else {
			var req = newAJAXRequest();
			req.open('GET', this.jyrcServletURI+'?jyrcid='+encodeURIComponent(this.jyrcid), true);
			req.onreadystatechange = function() { if(req.readyState != 4) return;
				if(req.status != 200) try {
					client.notify("I loose the connection with the jyrc server. Try to reload.");
					client.notify("[http error " + req.status + "]");
					return;
				} catch(e) { Components.utils.reportError(e); }
				var posts = req.responseXML.firstChild.childNodes;
				for(var i=0; i<posts.length; i++) try {
					client.notify(posts[i].firstChild.data,
							posts[i].getAttribute("author"),
							posts[i].getAttribute("date")
						     );
				} catch(e) { Components.utils.reportError(e); }
			}
			req.send(null);
		}
		if(this.isDaemonized)
			setTimeout(this.toSource()+".checkout();", this.checkoutInterval);
	}

	this.post = function(msg) { if(!this.jyrcid) return;
		var req = newAJAXRequest();
		req.open('POST', this.jyrcServletURI, true);
		req.onreadystatechange = function() { if(req.readyState != 4 || req.status == 200) return;
			try { client.notify("posting error [http code "+req.status+"]");
			} catch(e) { Components.utils.reportError(e); }
		}
		req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf8");
		req.send('jyrcid='+encodeURIComponent(this.jyrcid)+'&postvalue='+encodeURIComponent(msg));
	}

	this.refreshUserList = function() {
		try { this.clearUserList();
		} catch(e) { Components.utils.reportError(e); }
		this.post("/#names");
	}



	/**
	 * You should override this methods (but only if you want your client to work).
	 * Please note that this is this.notify job to invoke other notification functions.
	 */

	this.notify		= function(msg,auth,d) /* throws exceptions */ {}
	this.clearUserList	= function() /* thorws exceptions */ {}

	this.notifyUserEntrance	= function(user) {}
	this.notifyUserExit	= function(user) {}
	this.notifyTopicChange	= function(newtopic) {}
}





function newAJAXRequest() {
	if(window.XMLHttpRequest)	return new XMLHttpRequest();
	if(window.ActiveXObject)	return new ActiveXObject("Microsoft.XMLHTTP");
	return null;
}
